package com.ruoyi.tb.lmt.controller;

import java.security.Security;
import java.util.Date;
import java.util.List;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

import cn.dev33.satoken.annotation.SaIgnore;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.GuidUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.tb.lmt.domain.TEquipmentLog;
import com.ruoyi.tb.lmt.domain.bo.TEquipmentBo;
import com.ruoyi.tb.lmt.domain.bo.TbMessageNoticeBo;
import com.ruoyi.tb.lmt.domain.vo.TEquipmentVo;
import com.ruoyi.tb.lmt.domain.vo.TbLmtrepairWorkdetailVo;
import com.ruoyi.tb.lmt.mapper.TEquipmentLogMapper;
import com.ruoyi.tb.lmt.mapper.TbLocomotiveMapper;
import com.ruoyi.tb.lmt.service.ITEquipmentService;
import com.ruoyi.tb.lmt.service.ITbMessageNoticeService;
import com.ruoyi.tb.lmt.service.TEquipmentLogService;
import lombok.RequiredArgsConstructor;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;

import cn.dev33.satoken.annotation.SaCheckPermission;
import org.apache.catalina.security.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.core.validate.QueryGroup;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.tb.lmt.domain.vo.TbEquipmentApplyVo;
import com.ruoyi.tb.lmt.domain.bo.TbEquipmentApplyBo;
import com.ruoyi.tb.lmt.service.ITbEquipmentApplyService;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 大部件申请
 *
 * @author ruoyi
 * @date 2024-04-03
 */
//@SaIgnore
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/xha-lmt/equipmentApply")
public class TbEquipmentApplyController extends BaseController {

    private final ITbEquipmentApplyService iTbEquipmentApplyService;


    @Autowired
    private ITEquipmentService itEquipmentService;
    @Autowired
    private TbLocomotiveMapper tbLocomotiveMapper;

    @Autowired
    private TEquipmentLogService tEquipmentLogService;
    @Autowired
    private ITbMessageNoticeService iTbMessageNoticeService;

    @Autowired
    private ISysRoleService iSysRoleService;

    /**
     * 查询大部件申请列表
     */
    @GetMapping("/list")
    public TableDataInfo<TbEquipmentApplyVo> list(TbEquipmentApplyBo bo, PageQuery pageQuery) {
        return iTbEquipmentApplyService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出大部件申请列表
     */
    @Log(title = "大部件申请", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(TbEquipmentApplyBo bo, HttpServletResponse response) {
        List<TbEquipmentApplyVo> list = iTbEquipmentApplyService.queryList(bo);
        ExcelUtil.exportExcel(list, "大部件申请", TbEquipmentApplyVo.class, response);
    }

    /**
     * 获取大部件申请详细信息
     *
     * @param ID 主键
     */
    @GetMapping("/{ID}")
    public R<TbEquipmentApplyVo> getInfo(@NotNull(message = "主键不能为空")
                                         @PathVariable Long ID) {
        return R.ok(iTbEquipmentApplyService.queryById(ID));
    }

    @Log(title = "提交大部件申请", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/add1")
    public R add1(@Validated TbEquipmentApplyBo bo) {
        if (StringUtils.isBlank(bo.getStatus())) {
            if (isAdmin(LoginHelper.getLoginUser().getUsername())) {
                bo.setStatus("已通过");
            } else {
                bo.setStatus("车间副主任审批中");
            }
        }
        bo.setSubmissionTime(new Date());
        iTbEquipmentApplyService.insertByBo(bo);
        return R.ok();
    }

    /**
     * 提交大部件申请
     */
    //@SaCheckPermission("xha-lmt:equipmentApply:add")
    @Log(title = "提交大部件申请", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/add")
    public R<Void> add(@Validated(AddGroup.class) @RequestBody TbEquipmentApplyBo bo) {
        if (StringUtils.isBlank(bo.getStatus())) {
            bo.setStatus("车间副主任审批中");
        }
        //todo 设置审批人
        //第一步设置审批人为车间副主任
        String deputyDirector = iTbMessageNoticeService.getDeputyDirector(bo.getWorkGroupId());
        bo.setApprovedBy(deputyDirector);
        //设置提交时间
        bo.setSubmissionTime(new Date());

        // 这里判断是新增还是更新操作
        Boolean result;
        if (bo.getID() == null) {
            result = iTbEquipmentApplyService.insertByBo(bo);
        } else {
            result = iTbEquipmentApplyService.updateByBo(bo);
        }

        if (result) {
            // 提交成功后，发送消息通知
            TbMessageNoticeBo messageNoticeBo = new TbMessageNoticeBo();
            LoginUser currentUser = LoginHelper.getLoginUser();
            messageNoticeBo.setMessageTitle(bo.getLmtNumber() + "车高价件申请");
            messageNoticeBo.setMessageName(currentUser.getUsername() + "申请高价件,请及时处理。");
            messageNoticeBo.setMessageType("高价件申请");
            messageNoticeBo.setLmtType(tbLocomotiveMapper.selectLmtTypeByLmtNumber(bo.getLmtNumber()));
            messageNoticeBo.setLmtNumber(bo.getLmtNumber());
            messageNoticeBo.setWorkGroup(bo.getWorkGroup());
            messageNoticeBo.setWorkUser(currentUser.getUsername());
            messageNoticeBo.setStatus("0");
            messageNoticeBo.setWorkGroupId(bo.getWorkGroupId());
            messageNoticeBo.setWorkTime(new Date());
            //todo 设置接收人
            //第一次提交，也设置接收人为车间副主任
            messageNoticeBo.setRecipient(deputyDirector);
            iTbMessageNoticeService.insertByBo(messageNoticeBo);

        }
        return toAjax(result);
    }


    /**
     * 暂存大部件申请
     */
    //@SaCheckPermission("xha-lmt:equipmentApply:temporary")
    @Log(title = "暂存大部件申请", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/temporary")
    public R<Void> temporary(@Validated(AddGroup.class) @RequestBody TbEquipmentApplyBo bo) {

        bo.setStatus("暂存");
        //todo 设置审批人
        String deputyDirector = iTbMessageNoticeService.getDeputyDirector(bo.getWorkGroupId());
        bo.setApprovedBy(deputyDirector);

        // 这里判断是新增还是更新操作
        Boolean result;
        if (bo.getID() == null) {
            result = iTbEquipmentApplyService.insertByBo(bo);
        } else {
            result = iTbEquipmentApplyService.updateByBo(bo);
        }
        return toAjax(result);
    }

    /**
     * 大部件申请通过
     */
    @SaCheckPermission("xha-lmt:equipmentApply:edit")
    @Log(title = "大部件申请通过", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/approve")
    public R<Void> approve(@Validated(EditGroup.class) @RequestBody TbEquipmentApplyBo bo) {
        bo.setStatus("已通过");
        return toAjax(iTbEquipmentApplyService.updateByBo(bo));
    }

    /**
     * 车间副主任审批
     */
    @SaCheckPermission("xha-lmt:equipmentApply:deputyDirectorApprove")
    @Log(title = "大部件申请通过", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/deputyDirectorApprove")
    public R<Void> deputyDirectorApprove(@RequestBody TbEquipmentApplyBo bo) {
        // 判断当前用户是否为对应车间的副主任
        String currentDeputyDirector = iTbMessageNoticeService.getDeputyDirector(bo.getWorkGroupId());
        String username = LoginHelper.getLoginUser().getUsername();
        if (!LoginHelper.getLoginUser().getUsername().equals(currentDeputyDirector) && !isAdmin(username)) {
            throw new IllegalArgumentException("您没有权限审批该申请");
        }

        // 更新状态为设备科审批中
        bo.setStatus("设备科审批中");
        // 设置设备科负责人
        bo.setApprovedBy2(iTbMessageNoticeService.getEquipmentDepartment());
        Boolean result = iTbEquipmentApplyService.updateByBo(bo);

        if (result) {
            // 提交成功后，发送消息通知
            TbMessageNoticeBo messageNoticeBo = new TbMessageNoticeBo();
            LoginUser currentUser = LoginHelper.getLoginUser();
            messageNoticeBo.setMessageTitle(bo.getLmtNumber() + "车高价件申请");
            messageNoticeBo.setMessageName(currentUser.getUsername() + "申请高价件,请及时处理。");
            messageNoticeBo.setMessageType("高价件申请");
            messageNoticeBo.setLmtType(tbLocomotiveMapper.selectLmtTypeByLmtNumber(bo.getLmtNumber()));
            messageNoticeBo.setLmtNumber(bo.getLmtNumber());
            messageNoticeBo.setWorkGroup(bo.getWorkGroup());
            messageNoticeBo.setWorkUser(currentUser.getUsername());
            messageNoticeBo.setStatus("0");
            messageNoticeBo.setWorkGroupId(bo.getWorkGroupId());
            messageNoticeBo.setWorkTime(new Date());
            messageNoticeBo.setMessageId(bo.getID());
            //todo 设置接收人
            //第二次提交，发送给设备科负责人
            messageNoticeBo.setRecipient(iTbMessageNoticeService.getEquipmentDepartment());
            iTbMessageNoticeService.insertByBo(messageNoticeBo);
        }

        return toAjax(result);
    }

    @Autowired
    private TEquipmentLogMapper tEquipmentLogMapper;

    @SaCheckPermission("xha-lmt:equipmentApply:equipmentApprove")
    @Log(title = "设备科审批通过", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/equipmentApprove")
    public R<Void> equipmentDepartmentApprove(@RequestBody TbEquipmentApplyBo bo) {
        // 判断当前用户是否为设备科人员
        // 你需要实现这个方法来检查当前用户是否有审批权限
        String username = LoginHelper.getLoginUser().getUsername();

        if (!isUserInEquipmentDepartment(username) && !isAdmin(username)) {
            throw new IllegalArgumentException("您没有权限审批该申请");
        }

        // 更新状态为已通过
        bo.setStatus("已通过");
        Boolean result = iTbEquipmentApplyService.updateByBo(bo);

        //TODO 旧高价件入库（旧高价件卸下入库日志）
        TEquipmentVo oldVo = itEquipmentService.queryByCode(bo.getOldEquipmentCode());
        //TODO 新高价件出库装车（新高价件出库装车日志）
        TEquipmentVo nowVo = itEquipmentService.queryByCode(bo.getEquipmentCode());
        if (oldVo != null && nowVo != null) {
            TEquipmentBo oldBo = new TEquipmentBo();
            oldBo.setStatus("待修");
            oldBo.setID(oldVo.getID());
            oldBo.setLmtNumber("");
            itEquipmentService.updateByBo(oldBo);
            //添加日志
            TEquipmentLog oldLog = new TEquipmentLog();
            oldLog.setEquipmentId(oldVo.getID());
            oldLog.setOprtType("卸下入库待修");
            oldLog.setOprtDate(DateUtils.getNowDate());
            oldLog.setRemark("从" + bo.getLmtNumber() + "车上拆下");
            tEquipmentLogService.insertEquipmentLog(oldLog);

            TEquipmentBo tbo = new TEquipmentBo();
            tbo.setStatus("运行中");
            tbo.setLmtNumber(bo.getLmtNumber());
            tbo.setID(nowVo.getID());
            itEquipmentService.updateByBo(tbo);
            //添加日志
            TEquipmentLog log = new TEquipmentLog();
            log.setEquipmentId(nowVo.getID());
            log.setOprtType("装车运行中");
            log.setOprtDate(DateUtils.getNowDate());
            log.setRemark("装到" + bo.getLmtNumber() + "车上");
            tEquipmentLogService.insertEquipmentLog(log);
        }
//        TEquipmentLog tEquipmentLog = new TEquipmentLog();
//        tEquipmentLog.setEquipmentId(bo.getEquipmentCode());
//
//        tEquipmentLogMapper.insert(tEquipmentLog);
        return toAjax(result);
    }

    public boolean isAdmin(String username) {
        // 通过用户名获取用户的所有角色
        List<SysRole> userRoles = iSysRoleService.selectRolesByUserName(username);

        // 检查用户是否有管理员角色
        for (SysRole role : userRoles) {
            if ("admin".equals(role.getRoleKey())) {
                return true;
            }
        }
        return false;
    }

    public boolean isUserInEquipmentDepartment(String username) {
        // 通过用户名获取用户的所有角色
        List<SysRole> userRoles = iSysRoleService.selectRolesByUserName(username);

        // 检查用户是否有设备科的角色标识
        for (SysRole role : userRoles) {
            if ("equipmentDept".equals(role.getRoleKey())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 大部件申请驳回
     */
    @SaCheckPermission("xha-lmt:equipmentApply:reject")
    @Log(title = "大部件申请驳回", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/reject")
    public R<Void> reject(@Validated(EditGroup.class) @RequestBody TbEquipmentApplyBo bo) {
        bo.setStatus("已驳回");

        //发送消息通知
        TbMessageNoticeBo messageNoticeBo = new TbMessageNoticeBo();
        LoginUser currentUser = LoginHelper.getLoginUser();
        messageNoticeBo.setMessageTitle(bo.getLmtNumber() + "车高价件申请");
        messageNoticeBo.setMessageName(currentUser.getUsername() + "驳回了高价件申请,请及时处理。");
        messageNoticeBo.setMessageType("高价件申请");
        messageNoticeBo.setLmtType(tbLocomotiveMapper.selectLmtTypeByLmtNumber(bo.getLmtNumber()));
        messageNoticeBo.setLmtNumber(bo.getLmtNumber());
        messageNoticeBo.setWorkGroup(bo.getWorkGroup());
        messageNoticeBo.setWorkUser(currentUser.getUsername());
        messageNoticeBo.setStatus("0");
        messageNoticeBo.setWorkGroupId(bo.getWorkGroupId());
        messageNoticeBo.setWorkTime(new Date());
        //todo 设置接收人
        messageNoticeBo.setRecipient(bo.getCreateBy());
        iTbMessageNoticeService.insertByBo(messageNoticeBo);
        return toAjax(iTbEquipmentApplyService.updateByBo(bo));
    }

    /**
     * 修改大部件申请
     */
    //@SaCheckPermission("xha-lmt:equipmentApply:edit")
    @Log(title = "大部件申请", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody TbEquipmentApplyBo bo) {
        return toAjax(iTbEquipmentApplyService.updateByBo(bo));
    }

    /**
     * 删除大部件申请
     *
     * @param IDs 主键串
     */
    //@SaCheckPermission("xha-lmt:equipmentApply:remove")
    @Log(title = "大部件申请", businessType = BusinessType.DELETE)
    @DeleteMapping("/{IDs}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] IDs) {
        return toAjax(iTbEquipmentApplyService.deleteWithValidByIds(Arrays.asList(IDs), true));
    }

    /**
     * 查询大部件申请列表
     */
    //@SaCheckPermission("xha-lmt:equipmentApply:list")
    @GetMapping("/applyList")
    public TableDataInfo<TbEquipmentApplyVo> applyList(PageQuery pageQuery) {
        return iTbEquipmentApplyService.selectApplyList(pageQuery);
    }


}
